package com.hgl.bi.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hgl.bi.common.constant.ErrorCode;
import com.hgl.bi.common.manager.RedisManager;
import com.hgl.bi.common.model.dto.PageDTO;
import com.hgl.bi.common.model.vo.R;
import com.hgl.bi.common.utils.AssertUtil;
import com.hgl.bi.common.utils.ConvertUtil;
import com.hgl.bi.web.entity.SetEntity;
import com.hgl.bi.web.mapper.SetMapper;
import com.hgl.bi.web.model.dto.SetSaveDto;
import com.hgl.bi.web.model.dto.SetUpdateDto;
import com.hgl.bi.web.model.dto.SharedSetDto;
import com.hgl.bi.web.model.dto.UserInfoDto;
import com.hgl.bi.web.model.vo.FileVo;
import com.hgl.bi.web.service.SetService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;

/**
 * @program: BI
 * @description: 数据集管理控制层
 * @author: hgl
 * @create: 2025-02-15 00:26
 */
@Tag(name = "数据集管理模块")
@RestController
public class SetController {

    @Autowired
    private SetService setService;

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private SetMapper setMapper;

    /**
     * 统计分享数据集数量
     *
     * @param satoken
     * @return 数据集数量
     */
    @Operation(summary = "统计分享数据集次数", tags = "数据集管理模块")
    @GetMapping("/set/shared/count")
    public R<Long> countSharedSets(@RequestHeader("satoken") String satoken) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();

        long count = setService.countSharedSets(userId);
        return R.success(count);
    }

    /**
     * 获取角色权限
     * @param id 角色ID
     * @return 角色权限
     * @author hgl
     */
    @Operation(summary = "查询分享用户", tags = "数据集管理模块")
    @GetMapping("/set/shared/users/{id}")
    public R<List<Long>> getSharedUsers(@RequestHeader("satoken") String satoken,
                                        @PathVariable Long id) {
        // 非空校验
        AssertUtil.notNull(id, ErrorCode.REQUEST_PARAM_ERROR);
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        List<Long> users = setService.getSharedUsers(userId, id);
        return R.success(users);
    }

    /**
     * 分页查询分享数据集
     *
     * @param pageDto 分页信息
     * @return 数据集分页信息
     * @author hgl
     *
     */
    @Operation(summary = "分页查询分享数据集", tags = "数据集管理模块")
    @GetMapping("/set/shared/list")
    public R<Page<SetEntity>> listSharedSets(@RequestHeader("satoken") String satoken,
                                       @ParameterObject PageDTO pageDto) {
        // 非空校验
        AssertUtil.notNull(pageDto, ErrorCode.REQUEST_PARAM_ERROR);
        // 分页查询

        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        Page<SetEntity> setPage = setService.sharedPage(userId, pageDto);
        return R.success(setPage);
    }

    @Operation(summary = "分享数据集", tags = "数据集管理模块")
    @PutMapping("/set/shared")
    public R<String> sharedSet(@RequestHeader("satoken") String satoken,
                               @RequestBody SharedSetDto sharedSetDto) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();

        setService.sharedSet(userId, sharedSetDto);
        return R.ok("分享成功");
    }


    @Operation(summary = "取消分享数据集", tags = "数据集管理模块")
    @DeleteMapping("/set/remove/shared")
    public R<String> removeSharedSet(@RequestHeader("satoken") String satoken,
                               @RequestBody SharedSetDto sharedSetDto) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();

        setService.removeSharedSet(userId, sharedSetDto);
        return R.ok("取消分享成功");
    }

    /**
     * 查询关联文件
     * @return 数据集列表
     * @author hgl
     */
    @Operation(summary = "查询关联文件", tags = "数据集管理模块")
    @GetMapping("/set/list/associated/{id}")
    public R<List<FileVo>> getAssociatedFiles(@PathVariable Long id) {
        // 非空校验
        AssertUtil.notNull(id, ErrorCode.REQUEST_PARAM_ERROR);
        // 查询数据集
        List<FileVo> list = setService.getAssociatedFiles(id);
        return R.success(list);
    }

    /**
     * 获取所有数据集
     * @return 数据集列表
     * @author hgl
     */
    @Operation(summary = "查询所有数据集", tags = "数据集管理模块")
    @GetMapping("/set/list/all")
    public R<List<SetEntity>> getAllSets(@RequestHeader("satoken") String satoken) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        List<SetEntity> list;
        if (!userInfo.getRole().equals("admin")) {
            QueryWrapper<SetEntity> wrapper = new QueryWrapper<SetEntity>()
                    .eq("user_id", userId);
            list = setService.list(wrapper);
        } else {
            list = setService.list();
        }
        return R.success(list);
    }

    /**
     * 统计数据集数量
     * @return 数据集数量
     */
    @Operation(summary = "统计数据集数量", tags = "数据集管理模块")
    @GetMapping("/set/count/sum")
    public R<Long> countDataSets(@RequestHeader("satoken") String satoken) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        long count;
        if (!userInfo.getRole().equals("admin")) {
            QueryWrapper<SetEntity> wrapper = new QueryWrapper<SetEntity>()
                    .eq("user_id", userId);
            count = setService.count(wrapper);
        } else {
            count = setService.count();
        }
        return R.success(count);
    }

    /**
     * 统计本月新增数据集
     * @return 本月新增数据集
     */
    @Operation(summary = "统计本月新增数据集", tags = "数据集管理模块")
    @GetMapping("/set/count/new")
    public R<Long> countNewDatasets(@RequestHeader("satoken") String satoken) {
        // 获取当前日期
        LocalDate now = LocalDate.now();
        // 当前月份的第一天
        LocalDate startOfMonth = now.withDayOfMonth(1);
        // 当前月份的最后一天
        LocalDate endOfMonth = startOfMonth.plusMonths(1).minusDays(1);
        // 转换为 LocalDateTime
        LocalDateTime start = startOfMonth.atStartOfDay(); // 当月第一天 00:00:00
        LocalDateTime end = endOfMonth.atTime(LocalTime.MAX); // 当月最后一天 23:59:59
        QueryWrapper<SetEntity> wrapper = new QueryWrapper<SetEntity>()
                .ge("created_time", start)
                .le("created_time", end);
        long count;
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        if (!userInfo.getRole().equals("admin")) {
            wrapper.eq("user_id", userId);
        }
        count = setService.count(wrapper);
        return R.success(count);
    }

    /**
     * 统计已分析数据集
     * @return 已分析数据集
     */
    @Operation(summary = "统计总分析次数", tags = "数据集管理模块")
    @GetMapping("/set/count/analyzed")
    public R<Long> countAnalyzedDatasets(@RequestHeader("satoken") String satoken) {

        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        Long count = setMapper.sumAnalyzeCount(userId);
        return R.success(count);
    }

    /**
     * 分页查询数据集列表
     *
     * @param pageDto 分页信息
     * @return 数据集分页信息
     * @author hgl
     */
    @Operation(summary = "查询数据集列表", tags = "数据集管理模块")
    @GetMapping("/set/list")
    public R<Page<SetEntity>> listSets(@RequestHeader("satoken") String satoken,
                                       @ParameterObject PageDTO pageDto) {
        // 非空校验
        AssertUtil.notNull(pageDto, ErrorCode.REQUEST_PARAM_ERROR);
        // 分页查询
        Page<SetEntity> page = new Page<>(pageDto.getPage(), pageDto.getSize());
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        QueryWrapper<SetEntity> wrapper = new QueryWrapper<SetEntity>()
                .eq("user_id", userId);
        if (pageDto.getKeyword() != null && !pageDto.getKeyword().isEmpty()) wrapper
                .like("set_name", pageDto.getKeyword());
        Page<SetEntity> setPage = setService.page(page, wrapper);
        return R.success(setPage);
    }

    /**
     * 获取数据集详情
     *
     * @param id 数据集ID
     * @return 数据集信息
     * @author hgl
     */
    @Operation(summary = "查询数据集详情", tags = "数据集管理模块")
    @GetMapping("/set/info/{id}")
    public R<SetEntity> getSetInfo(@PathVariable Long id) {
        // 非空校验
        AssertUtil.notNull(id, ErrorCode.REQUEST_PARAM_ERROR);
        // 查询数据集
        SetEntity set = setService.getById(id);
        return R.success(set);
    }

    /**
     * 更新数据集信息
     *
     * @param set 数据集信息
     * @return R<String>
     * @author hgl
     */
    @Operation(summary = "更新数据集信息", tags = "数据集管理模块")
    @PostMapping("/set/update")
    public R<String> updateSetInfo(@RequestBody SetUpdateDto set) {
        // 非空校验
        AssertUtil.notNull(set, ErrorCode.REQUEST_PARAM_ERROR);
        // 更新数据集
        UpdateWrapper<SetEntity> wrapper = new UpdateWrapper<SetEntity>()
                .eq("id", set.getId());
        if (set.getSetName() != null) wrapper.set("set_name", set.getSetName());
        if (set.getSetDesc() != null) wrapper.set("set_desc", set.getSetDesc());
        if (set.getTagId() != null) wrapper.set("tag_id", set.getTagId());
        boolean updated = setService.update(wrapper);
        AssertUtil.isTrue(updated, ErrorCode.UPDATE_FALSE);
        return R.ok("更新成功");
    }

    /**
     * 保存数据集信息
     *
     * @param set 数据集信息
     * @return R<String>
     * @author hgl
     */
    @Operation(summary = "保存数据集信息", tags = "数据集管理模块")
    @PutMapping("/set/save")
    public R<String> saveSetInfo(@RequestHeader("satoken") String satoken,
                                 @RequestBody SetSaveDto set) {
        // 非空校验
        AssertUtil.notNull(set, ErrorCode.REQUEST_PARAM_ERROR);
        // 保存数据集
        SetEntity setEntity = ConvertUtil.convertObject(set, SetEntity.class, null);
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long id = userInfo.getId();
        setEntity.setUserId(id);
        setEntity.setCreatedTime(new Date());
        boolean saved = setService.save(setEntity);
        AssertUtil.isTrue(saved, ErrorCode.SAVE_FALSE);
        return R.ok("保存成功");
    }

    /**
     * 删除数据集信息
     *
     * @param id 数据集ID
     * @return R<String>
     * @author hgl
     */
    @Operation(summary = "删除数据集信息", tags = "数据集管理模块")
    @DeleteMapping("/set/remove/{id}")
    public R<String> removeSetInfo(@PathVariable Long id) {
        // 非空校验
        AssertUtil.notNull(id, ErrorCode.REQUEST_PARAM_ERROR);
        // 删除用户
        boolean removed = setService.removeById(id);
        AssertUtil.isTrue(removed, ErrorCode.REMOVE_FALSE);
        return R.ok("删除成功");
    }
}
